package com.woniu.gym.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.core.exception.account.AccountException;
import com.woniu.core.exception.account.AccountExceptionCode;
import com.woniu.core.exception.gym.GymException;
import com.woniu.core.exception.gym.GymExceptionCode;
import com.woniu.core.exception.order.OrderException;
import com.woniu.core.exception.order.OrderExceptionCode;
import com.woniu.core.util.GaoDeMapUtil;
import com.woniu.core.util.JwtUtil;
import com.woniu.core.util.PageInfo;
import com.woniu.core.util.Result;
import com.woniu.gym.client.AccountServerClient;
import com.woniu.gym.client.OrderServerClient;
import com.woniu.gym.client.dto.AddGymEnterOrderDto;
import com.woniu.gym.client.dto.GymAccountDto;
import com.woniu.gym.client.form.AddGymEnterOrderForm;
import com.woniu.gym.dao.TGymBaseMapper;
import com.woniu.gym.dao.TQualificationMapper;
import com.woniu.gym.dto.QualificationDto;
import com.woniu.gym.dto.RegistryGymDto;
import com.woniu.gym.form.*;
import com.woniu.gym.model.TGymBase;
import com.woniu.gym.model.TQualification;
import com.woniu.gym.service.TQualificationService;
import io.seata.spring.annotation.GlobalTransactional;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年04月02日
 */
@Service
public class TQualificationServiceImpl extends ServiceImpl<TQualificationMapper, TQualification> implements TQualificationService {
    @Resource
    private AccountServerClient accountServerClient;
    @Resource
    private OrderServerClient orderServerClient;

    @Resource
    private TGymBaseMapper tGymBaseMapper;
    @Resource
    private TQualificationMapper tQualificationMapper;
    @Override
    public RegistryGymDto registryGym(RegistryGymForm form) {
        Result<GymAccountDto> dtoResult = accountServerClient.findGymAccountById(form.getGymId());
        if(dtoResult.getCode()!=200){
            throw new GymException(dtoResult.getMsg(),dtoResult.getCode());
        }
        GymAccountDto gymAccountDto = dtoResult.getData();
        if(gymAccountDto.getAccountState()==0){
            throw new AccountException(AccountExceptionCode.STORE_IS_FREEZE);
        }
        boolean numeric2 = JwtUtil.isNumeric2(form.getGymSite());
        if (numeric2) throw new AccountException("地址不能为纯数字",40061);
        boolean bb = form.getGymSite().matches("[a-zA-Z]+");
        if (bb) throw new AccountException("地址不能为纯英文",40061);

        TQualification tq = BeanUtil.toBean(form, TQualification.class);
        JSONObject positionObj = GaoDeMapUtil.getLngAndLat(form.getGymSite());
        String longitude = positionObj.getString("longitude");
        String latitude = positionObj.getString("latitude");

        tq.setGymLongitude(Double.parseDouble(longitude));
        tq.setGymLatitude(Double.parseDouble(latitude));
        tq.setGymId(form.getGymId());
        tq.setCertifyState(0);
        boolean b = save(tq);
        if (!b) throw new AccountException(AccountExceptionCode.APPLICATION_FAILED_PLEASE_TRY_AGAIN);

        //返回前端
        RegistryGymDto dto = BeanUtil.toBean(tq, RegistryGymDto.class);
       return dto;
    }

    @Override
    public TQualification cancelRegistryGym(Integer certifyId) {
        TQualification qualification = tQualificationMapper.selectById(certifyId);
        if(qualification==null){
            throw new GymException(GymExceptionCode.QUALIFY_NOT_EXIST);
        }
        qualification.setCertifyState(3);
        tQualificationMapper.updateById(qualification);
        return qualification;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public TQualification adminApproveGym(AdminApproveGymForm form) {
        TQualification qualification = tQualificationMapper.selectById(form.getCertifyId());
        if(qualification==null){
            throw new GymException(GymExceptionCode.QUALIFY_NOT_EXIST);
        }
        if(qualification.getCertifyState()!=0){
            throw new OrderException(OrderExceptionCode.ORDER_HANDLE);
        }
        qualification.setCertifyState(form.getCertifyState());
        qualification.setOverruleCause(form.getOverruleCause());
        qualification.setApproveTime(LocalDateTime.now());
        tQualificationMapper.updateById(qualification);
        //审核通过
        if(form.getCertifyState()==1){
            //新增场馆基础信息表
            TGymBase tGymBase = new TGymBase();
            Snowflake snowflake = new Snowflake();
            tGymBase.setGymNum(snowflake.nextIdStr());
            tGymBase.setGymPhoto(qualification.getGymPhoto());
            tGymBase.setGymName(qualification.getGymName());
            tGymBase.setGymLicense(qualification.getGymLicense());
            tGymBase.setGymPermit(qualification.getGymPermit());
            tGymBase.setGymDetails(qualification.getGymDetails());
            tGymBase.setGymMark(0.00);
            tGymBase.setBusinessState(0);//歇业
            tGymBase.setGymState(0);//冻结，入住费支付后变1正常
            tGymBase.setInMoney(0);//入住费支付状态，默认未支付
            tGymBase.setCreateTime(LocalDateTime.now());
            tGymBase.setGymId(qualification.getGymId());
            tGymBase.setMarkNum(0);
            tGymBaseMapper.insert(tGymBase);

            //新增入驻费用订单表
            AddGymEnterOrderForm orderForm = new AddGymEnterOrderForm();
            orderForm.setGymId(qualification.getGymId());
            orderForm.setGymNum(tGymBase.getGymNum());
            orderForm.setAccountName(qualification.getGymLinkman());
            Result<AddGymEnterOrderDto> result = orderServerClient.addGymEnterOrder(orderForm);
            if(result.getCode()!=200){
                throw new OrderException(OrderExceptionCode.ADD_ORDER_EXIST);
            }
        }
        return qualification;
    }

    @Override
    public TQualification modifyRegistryGym(ModifyRegistryGymForm form) {
        TQualification qualification = tQualificationMapper.selectById(form.getCertifyId());
        if(qualification==null){
            throw new GymException(GymExceptionCode.QUALIFY_NOT_EXIST);
        }
        if(qualification.getCertifyState()!=2){
            throw new GymException(GymExceptionCode.MODIFY_STATE_EXCEPTION);
        }
        //把原来的状态变成取消
        qualification.setCertifyState(3);
        tQualificationMapper.updateById(qualification);
        //新增一条新的申请记录，以方便看之前的审核记录
        boolean numeric2 = JwtUtil.isNumeric2(form.getGymSite());
        if (numeric2) throw new AccountException("地址不能为纯数字",40061);
        boolean bb = form.getGymSite().matches("[a-zA-Z]+");
        if (bb) throw new AccountException("地址不能为纯英文",40061);

        JSONObject positionObj = GaoDeMapUtil.getLngAndLat(form.getGymSite());
        String longitude = positionObj.getString("longitude");
        String latitude = positionObj.getString("latitude");
        qualification.setCertifyId(null);
        qualification.setGymPhoto(form.getGymPhoto());
        qualification.setGymName(form.getGymName());
        qualification.setGymSite(form.getGymSite());
        qualification.setGymLicense(form.getGymLicense());
        qualification.setGymPermit(form.getGymPermit());
        qualification.setGymDetails(form.getGymDetails());
        qualification.setGymLinkman(form.getGymLinkman());
        qualification.setGymPhone(form.getGymPhone());
        qualification.setGymLongitude(Double.parseDouble(longitude));
        qualification.setGymLatitude(Double.parseDouble(latitude));
        qualification.setCertifyState(0);
        qualification.setApproveTime(null);
        qualification.setOverruleCause(null);
        boolean b = save(qualification);
        if (!b) throw new AccountException(AccountExceptionCode.APPLICATION_FAILED_PLEASE_TRY_AGAIN);
        return qualification;
    }

    @Override
    public PageInfo<QualificationDto> adminFindAllApply(AdminFindAllApplyForm form) {
        Page<TQualification> page = new Page<>(form.getPageNum()==null?1:form.getPageNum(),form.getPageSize()==null?5:form.getPageSize());
        QueryWrapper<TQualification> wrapper = new QueryWrapper<>();
        if(ObjectUtil.isAllNotEmpty(form.getCertifyState())){
            wrapper.eq("certify_state",form.getCertifyState());
        }
        if(ObjectUtil.isAllNotEmpty(form.getGymName())){
            wrapper.like("gym_name",form.getGymName());
        }
        tQualificationMapper.selectPage(page,wrapper);
        List<TQualification> list = page.getRecords();
        ArrayList<QualificationDto> data = new ArrayList<>();
        for (TQualification tqf : list) {
            QualificationDto dto = BeanUtil.toBean(tqf, QualificationDto.class);
            data.add(dto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setList(data);
        return pageInfo;
    }

    @Override
    public PageInfo<QualificationDto> gymFindApplyById(GymFindApplyByIdForm form) {
        Result<GymAccountDto> dtoResult = accountServerClient.findGymAccountById(form.getGymId());
        if(dtoResult.getCode()!=200){
            throw new GymException(dtoResult.getMsg(),dtoResult.getCode());
        }
        GymAccountDto gymAccountDto = dtoResult.getData();
        if(gymAccountDto.getAccountState()==0){
            throw new AccountException(AccountExceptionCode.STORE_IS_FREEZE);
        }
        Page<TQualification> page = new Page<>(form.getPageNum()==null?1:form.getPageNum(),form.getPageSize()==null?5:form.getPageSize());
        QueryWrapper<TQualification> wrapper = new QueryWrapper<>();
        wrapper.eq("gym_id",form.getGymId());
        if(ObjectUtil.isAllNotEmpty(form.getCertifyState())){
            wrapper.eq("certify_state",form.getCertifyState());
        }
        if(ObjectUtil.isAllNotEmpty(form.getGymName())){
            wrapper.like("gym_name",form.getGymName());
        }
        tQualificationMapper.selectPage(page,wrapper);
        List<TQualification> list = page.getRecords();
        ArrayList<QualificationDto> data = new ArrayList<>();
        for (TQualification tqf : list) {
            QualificationDto dto = BeanUtil.toBean(tqf, QualificationDto.class);
            data.add(dto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setList(data);
        return pageInfo;
    }
}
